package com.epalmpay.service.activity.impl;

import com.epalmpay.bean.OtherCouponBean;
import com.epalmpay.dto.activity.*;
import com.epalmpay.entity.Coupon;
import com.epalmpay.entity.CouponUser;
import com.epalmpay.entity.Member;
import com.epalmpay.entity.OtherCouponComfireRecord;
import com.epalmpay.entity.Page;
import com.epalmpay.enumdef.ActivityEnum;
import com.epalmpay.enumdef.BizEnum;
import com.epalmpay.exception.ApplicationException;
import com.epalmpay.mapper.ActivityBaseMapper;
import com.epalmpay.mapper.CouponMapper;
import com.epalmpay.mapper.CouponUserMapper;
import com.epalmpay.mapper.OtherCouponComfireRecordMapper;
import com.epalmpay.service.activity.IOtherCouponService;
import com.epalmpay.service.groupaccount.IGroupAccountService;
import com.epalmpay.util.DateUtil;
import com.epalmpay.util.PropertyCopyUtil;
import com.epalmpay.util.StringUtil;
import com.epalmpay.util.SysUtils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Administrator on 2017/9/25.
 */
@Service("otherCouponService")
public class IOtherCouponServiceImpl implements IOtherCouponService{
    @Resource
    private CouponMapper couponMapper;

    @Resource
    private ActivityBaseMapper activityBaseMapper;
    @Resource
    private CouponUserMapper couponUserMapper;
    
    @Resource
    private OtherCouponComfireRecordMapper otherCouponComfireRecordMapper;
    
    @Resource
	private IGroupAccountService groupAccountService;
    
    private ExecutorService exec;
    
    @PostConstruct
	public void initialize() {
		exec = Executors.newSingleThreadExecutor();
	}

    
    @Override    //列表
    public OtherCouponListOutDTO getOtherCouponList(OtherCouponInDTO couponInDTO,Page page) {

        OtherCouponListOutDTO result = new OtherCouponListOutDTO();

        Map<String,Object> param=new HashMap<String,Object>();
        param.put("groupId", couponInDTO.getGroupId());
        param.put("couponStatus", couponInDTO.getCouponStatus());
        param.put("name", couponInDTO.getName());
        param.put("purposeType", couponInDTO.getPurposeType());
        param.put("outStatus", couponInDTO.getExchangePlaceType());
        
        if(StringUtils.isNotBlank(couponInDTO.getIds())){
        	 param.put("ids", couponInDTO.getIds());
        }
        param.put("id", couponInDTO.getId());


        if(couponInDTO.getMemberId() !=null){
            List<OtherCouponOutDTO> otherCouponOutDTOList= new ArrayList<>();
            String[] ids = couponInDTO.getMemberId().split(",");
            for(int i= 0; i<ids.length;i++){
                param.put("id", ids[i]);
                OtherCouponOutDTO otherCouponOutDTO = couponMapper.findOtherCouponList(param);
                otherCouponOutDTOList.add(otherCouponOutDTO);
            }
            if(otherCouponOutDTOList.size()>0) {
                result.setOtherCouponOutDTOList(otherCouponOutDTOList);
            }
            return result;

        }else{
            param.put("id", couponInDTO.getId());

            int sumCount = couponMapper.selectOtherCouponListCount(param);
            page.setTotalResult(sumCount);
            if(sumCount<=0)
                return result;

            param.put("limit", page.getShowCount());
            param.put("start", page.getShowCount()*(page.getCurrentPage()-1));

            List<OtherCouponOutDTO> otherCouponOutDTOList = couponMapper.selectOtherCouponList(param);

            if(otherCouponOutDTOList.size()>0) {
                result.setOtherCouponOutDTOList(otherCouponOutDTOList);
            }
            return result;
        }
    }

    @Override
    public Long otherCouponSave(CouponAddInDTO couponAddInDTO) throws Exception {
        int result = 0;
        Integer freezeAmount = 0;
        Boolean autoAddFlag = Boolean.FALSE;

        Coupon record = new Coupon();
        if(couponAddInDTO.getValidTimeType() == ActivityEnum.CouponValidType.FixedTime.getType()){
            couponAddInDTO.setDays(null);
        }

        if(couponAddInDTO.getCouponType() == ActivityEnum.CouponType.FullSubCoupon.getType()){//满减券
            couponAddInDTO.setValue(couponAddInDTO.getValue()*100);//面值
            couponAddInDTO.setGoodsId(null);//商品id不为空
//            if(couponAddInDTO.getVerifyReadd() == 1)//不允许
//                couponAddInDTO.setVerifyReaddCount(-1);//核销叠加
            //计算冻结金额
//            if(couponAddInDTO.getSettedMode() ==1 ){//总部结算
//                if(couponAddInDTO.getTotalCount()==null||couponAddInDTO.getTotalCount()==0) {
//                    freezeAmount = Const.COUPON_FREEZE_AMOUNT;
//                    autoAddFlag = Boolean.TRUE;
//                }else{
//                    freezeAmount =  couponAddInDTO.getSettedValue()	* couponAddInDTO.getTotalCount();
//                }
//            }
        }


        PropertyCopyUtil.copyPropertiesExclude(couponAddInDTO,record);
        
        record.setGmtCreate(new Date());
        record.setGmtModified(new Date());
        if(couponAddInDTO.getTotalCount()<100){
        	record.setOutStatus(ActivityEnum.outStatus.Expired.getType());
        }else{
        	record.setOutStatus(ActivityEnum.outStatus.unCreate.getType());
        }
        record.setStatus(ActivityEnum.CouponStatus.UnSend.getType());
        record.setCreator(couponAddInDTO.getLoginId());
        record.setSumAmount(freezeAmount);
        record.setAutoAddFlag(autoAddFlag);
        record.setVerifiedCount(0);
        result = couponMapper.insertSelective(record);
        
        /**
         * 生成券码等待用户领取
         */
       if(couponAddInDTO.getTotalCount()<100){
    	   for(int i=0;i<couponAddInDTO.getTotalCount();i++){
           	CouponUser couponUser = new CouponUser();
   			couponUser.setGmtCreate(new Date());
   			couponUser.setGmtModified(new Date());
   		//取有效期
			Date validTime = null;
			Date validStartTime = null;
			if (record.getValidTimeType() == ActivityEnum.CouponValidType.FixedTime.getType()) {
				validStartTime = record.getValidStartTime();
				validTime = record.getValidEndTime();
			} else if (record.getValidTimeType() == ActivityEnum.CouponValidType.ValidAfterGet.getType()) {
				validStartTime = new Date();
				validTime = DateUtil.getAfterDay(record.getDays());
			}
			couponUser.setValidStartTime(validStartTime);
			couponUser.setValidTime(validTime);
   			String couponCode=SysUtils.createCouponCode(record.getId(),record.getTotalCount(),i);
   			couponUser.setCouponCode(couponCode);// 优惠券码生成规则
   			couponUser.setCouponId(record.getId());
   			couponUser.setCouponUseStatus(ActivityEnum.CouponUseStatus.UnReceive
   					.getType());//		
   			couponUser.setGroupId(record.getGroupId());
   			 result = couponUserMapper.insertSelective(couponUser);
           }
       }
		//异业联盟优惠券不处理营销账户
        groupAccountService.updateAmount(couponAddInDTO.getGroupId(),
				BizEnum.SaleAccountSubjectType.CouponCreate, freezeAmount, record.getId(), null, null);

        return record.getId();
    }

    
	@Override
	public List<Coupon> findNeedCreateCodeInfo() {
		
		return couponMapper.findUnCreateCodeCoupon();
	}
	@Override
	public void finishCreateCodeInfo(Long id) {
		 Coupon record =couponMapper.selectByPrimaryKey(id);
		 if(record.getOutStatus().equals(ActivityEnum.outStatus.unCreate.getType())){
			 for(int i=0;i<record.getTotalCount();i++){
		           	CouponUser couponUser = new CouponUser();
		   			couponUser.setGmtCreate(new Date());
		   			couponUser.setGmtModified(new Date());
		   		//取有效期
					Date validTime = null;
					Date validStartTime = null;
					if (record.getValidTimeType() == ActivityEnum.CouponValidType.FixedTime.getType()) {
						validStartTime = record.getValidStartTime();
						validTime = record.getValidEndTime();
					} else if (record.getValidTimeType() == ActivityEnum.CouponValidType.ValidAfterGet.getType()) {
						validStartTime = new Date();
						validTime = DateUtil.getAfterDay(record.getDays());
					}
					couponUser.setValidStartTime(validStartTime);
					couponUser.setValidTime(validTime);
		   			String couponCode=SysUtils.createCouponCode(record.getId(),record.getTotalCount(),i);
		   			couponUser.setCouponCode(couponCode);// 优惠券码生成规则
		   			couponUser.setCouponId(record.getId());
		   			couponUser.setCouponUseStatus(ActivityEnum.CouponUseStatus.UnReceive
		   					.getType());//		
		   			couponUser.setGroupId(record.getGroupId());
		   			   couponUserMapper.insertSelective(couponUser);
		      }
			 record.setOutStatus(ActivityEnum.outStatus.Expired.getType());
			 record.setGmtModified(new Date());
			 couponMapper.updateByPrimaryKeySelective(record);
		 }
	}
	
	  /**
     * 异步执行
     */
    public void saveSynCreateCodeInfo( final Long couponId) {
    	exec.submit((new Runnable() {
  			@Override
  			public void run() { 
  				finishCreateCodeInfo(couponId);
  			}
  		}));
  		
	}
	
    @Override
    public CouponDetailOutDTO getOtherCouponDetail(OtherCouponInDTO couponInDTO, Page page) throws Exception {
        CouponDetailOutDTO result = new CouponDetailOutDTO();

        Coupon coupon =  couponMapper.queryCouponDetailById(couponInDTO.getId());

        CouponOutDTO couponOutDTO = new CouponOutDTO();
        PropertyCopyUtil.copyPropertiesExclude(coupon,couponOutDTO);
        result.setCouponOutDTO(couponOutDTO);

        //取得关联活动名称
        Map<String,Object> param=new HashMap<String,Object>();
//        param.put("couponId", couponInDTO.getId());
//        result.setActivityBaseList(activityBaseMapper.selectActiityByCouponId(param));

        //取得优惠券使用记录
        param.clear();
        param.put("couponId", couponInDTO.getId());
        param.put("couponUseStatus", couponInDTO.getCouponUseStatus());
        param.put("startDate", couponInDTO.getStartDate());
        param.put("endDate", couponInDTO.getEndDate());
        param.put("name", couponInDTO.getName());

        int sumCount = couponUserMapper.selectCouponUserListCount(param);
        page.setTotalResult(sumCount);
        if(sumCount>0){
            param.put("limit", page.getShowCount());
            param.put("start", page.getShowCount()*(page.getCurrentPage()-1));
            result.setCouponUserDTOList(couponUserMapper.selectCouponUserList(param));
        }

        return result;
    }


    @Override
    public void updateOtherCoupon(OtherCouponInDTO otherCouponInDTO) throws Exception {
        Coupon coupon = new Coupon();
        coupon.setId(otherCouponInDTO.getId());
        coupon.setOutStatus(ActivityEnum.outStatus.Received.getType());
        coupon.setGmtModified(new Date());
        coupon.setReceiveGroupid(otherCouponInDTO.getReceiveGroupid());
        couponMapper.updateByPrimaryKeySelective(coupon);
    }

	@Override
	public OtherCouponExporListOutDTO getOtherCouponExporList(OtherCouponInDTO couponInDTO) throws Exception {
		OtherCouponExporListOutDTO out=new OtherCouponExporListOutDTO();
		List<OtherCouponBean> couponInfos = couponUserMapper.findAllByCouponId(couponInDTO.getId());
		out.setCouponInfos(couponInfos);
		return out;
	}

	/**
	 * 完成异业联盟优惠券的导入
	 */
	@Override
	public void finihsOtherCoupon(OtherCouponImportInDTO otherCouponImportInDTO) throws Exception {
		
		try {
			Long importGroupId=otherCouponImportInDTO.getGroupId();
			 List<OtherCouponBean> couponInfos =otherCouponImportInDTO.getCouponInfos();
			if(couponInfos.size()>0){
				OtherCouponBean otherCouponBean=couponInfos.get(0);
				Long creatGroupId=SysUtils.Object2Long(otherCouponBean.getGroupId());
				if(importGroupId.equals(creatGroupId)){
					throw new ApplicationException("异业联盟优惠券，生成方和发送方不能相同");
				}				
				Long coupoId=SysUtils.Object2Long(otherCouponBean.getCouponId());
				Coupon	coupon=couponMapper.selectByPrimaryKey(coupoId);
				if(coupon.getReceiveGroupid()!=null&&!coupon.getReceiveGroupid().equals(importGroupId)){
					throw new ApplicationException("异业联盟优惠券，同一批优惠券不能导入不同的渠道");
				}
				for(OtherCouponBean bean:couponInfos){
					if(!coupoId.equals(SysUtils.Object2Long(bean.getCouponId()))){
						throw new ApplicationException("每次导入的优惠券必须是同一优惠券");
					}
					CouponUser couponUser=couponUserMapper.selectByCouponSn(bean.getCouponCode());
					if(!couponUser.getCouponId().equals(coupoId)){
						throw new ApplicationException("数据格式错误，券码："+bean.getCouponCode()+"优惠券不对应");
					}
				}
				Coupon couponUpdate=new Coupon();
			    couponUpdate.setId(coupoId);
				couponUpdate.setOutStatus(ActivityEnum.outStatus.Received.getType());
				couponUpdate.setStatus(ActivityEnum.CouponStatus.Getting.getType());
				couponUpdate.setGmtModified(new Date());
				couponUpdate.setReceiveGroupid(importGroupId);
			    couponMapper.updateByPrimaryKeySelective(couponUpdate);
				
			}
		} catch (ApplicationException ae) {
			ae.printStackTrace();
			throw ae;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("文件格式错误");
		}
	}

	@Override
	public void finishOCouponApply(OtherCouponComfireInDTO otherCouponInDTO) throws Exception {
		
		OtherCouponComfireRecord oComfireRecord=new OtherCouponComfireRecord();
        PropertyCopyUtil.copyProperties(otherCouponInDTO, oComfireRecord);
        oComfireRecord.setGmtCreate(new Date());
        oComfireRecord.setProcessStatus(ActivityEnum.OtherCouponApply.SUBMIT.getType());
        
        Coupon coupon=couponMapper.selectByPrimaryKey(otherCouponInDTO.getCouponId());
        coupon.setStatus(ActivityEnum.CouponStatus.onSend.getType());
        oComfireRecord.setGroupId(coupon.getGroupId());
        couponMapper.updateByPrimaryKeySelective(coupon);
        otherCouponComfireRecordMapper.insert(oComfireRecord);
	}

	@Override
	public void finishOCouponDelete(OtherCouponComfireInDTO otherCouponInDTO) throws Exception {
		OtherCouponComfireRecord otherCouponComfireRecord=otherCouponComfireRecordMapper.selectByPrimaryKey(otherCouponInDTO.getId());
		otherCouponComfireRecordMapper.deleteByPrimaryKey(otherCouponInDTO.getId());
		   Coupon coupon=couponMapper.selectByPrimaryKey(otherCouponComfireRecord.getCouponId());
	        coupon.setStatus(ActivityEnum.CouponStatus.UnSend.getType());
	        couponMapper.updateByPrimaryKeySelective(coupon);
	}

	@Override
	public void finishOCouponComfire(OtherCouponComfireInDTO otherCouponInDTO) throws Exception {
		OtherCouponComfireRecord otherCouponComfireRecord=otherCouponComfireRecordMapper.selectByPrimaryKey(otherCouponInDTO.getId());
		if(!otherCouponComfireRecord.getProcessStatus().equals(ActivityEnum.OtherCouponApply.SUBMIT.getType())){
			throw new Exception("记录状态不对");
		}
		
		otherCouponComfireRecord.setGmtModified(new Date());
		otherCouponComfireRecord.setProcessRemark(otherCouponInDTO.getProcessRemark());
		otherCouponComfireRecord.setProcessStatus(otherCouponInDTO.getProcessStatus());
		otherCouponComfireRecord.setProcessUserId(otherCouponInDTO.getProcessUserId());
		otherCouponComfireRecordMapper.updateByPrimaryKey(otherCouponComfireRecord);
		Coupon couponUpdate=new Coupon();   
		    couponUpdate.setId(otherCouponComfireRecord.getCouponId());
		if(otherCouponInDTO.getProcessStatus().equals(ActivityEnum.OtherCouponApply.APPROVE_SUCCESS.getType())){
			   
				couponUpdate.setOutStatus(ActivityEnum.outStatus.Received.getType());
				couponUpdate.setStatus(ActivityEnum.CouponStatus.Getting.getType());
				couponUpdate.setGmtModified(new Date());
				couponUpdate.setReceiveGroupid(otherCouponInDTO.getReceiveGroupId());
			    couponMapper.updateByPrimaryKeySelective(couponUpdate);
		}else{		
			couponUpdate.setStatus(ActivityEnum.CouponStatus.UnSend.getType());
		     couponMapper.updateByPrimaryKeySelective(couponUpdate);
		}
	}

	@Override
	public OCouponComfireListOutDTO otherCouponComfireList(OtherCouponComfireInDTO couponInDTO, Page page) throws Exception {
		OCouponComfireListOutDTO result = new OCouponComfireListOutDTO();

	        Map<String,Object> param=new HashMap<String,Object>();
	        param.put("groupId", couponInDTO.getGroupId());
	        param.put("processStatus", couponInDTO.getProcessStatus());
//	        param.put("startDate", couponInDTO.get());
//	        param.put("endDate", couponInDTO.getProcessStatus());
	        
	        int sumCount = otherCouponComfireRecordMapper.selectOCComfireListCount(param);
            page.setTotalResult(sumCount);
            if(sumCount<=0)
                return result;

            param.put("limit", page.getShowCount());
            param.put("start", page.getShowCount()*(page.getCurrentPage()-1));

            List<OCouponComfireInfoOutDTO> otherCouponOutDTOList = otherCouponComfireRecordMapper.selectOCComfireList(param);

            if(otherCouponOutDTOList.size()>0) {
                result.setOtherCouponOutDTOList(otherCouponOutDTOList);
            }
            return result;
	}

	@Override
	public OCouponComfireInfoOutDTO otherCouponComfireInfo(Long id,Integer status) throws Exception {
		OCouponComfireInfoOutDTO otherCouponComfireRecord=otherCouponComfireRecordMapper.selectInfoByPrimaryKey(id,status);
		return otherCouponComfireRecord;
	}




}
